package com.mujin.keji.collectionsystem.module.updata.views;

import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.mujin.keji.collectionsystem.CcsApplication;
import com.mujin.keji.collectionsystem.Constant;
import com.mujin.keji.collectionsystem.R;
import com.mujin.keji.collectionsystem.base.BaseActivity;
import com.mujin.keji.collectionsystem.base.BaseVo;
import com.mujin.keji.collectionsystem.common.EmailSituationEnum;
import com.mujin.keji.collectionsystem.common.ErrorEnum;
import com.mujin.keji.collectionsystem.common.HouseApplianceEnum;
import com.mujin.keji.collectionsystem.common.InnerDecorationEnum;
import com.mujin.keji.collectionsystem.common.LivingSituationEnum;
import com.mujin.keji.collectionsystem.common.RepayPowerEnum;
import com.mujin.keji.collectionsystem.common.SyncDataMethod;
import com.mujin.keji.collectionsystem.common.VisitHouseEnum;
import com.mujin.keji.collectionsystem.common.VisitStatusEnum;
import com.mujin.keji.collectionsystem.db.dao.VisitDao;
import com.mujin.keji.collectionsystem.db.database.AppDataBase;
import com.mujin.keji.collectionsystem.db.domain.SaveVisitRecordBean;
import com.mujin.keji.collectionsystem.db.domain.VisitApplyBean;
import com.mujin.keji.collectionsystem.db.domain.VisitCountBean;
import com.mujin.keji.collectionsystem.dto.ParamVo;
import com.mujin.keji.collectionsystem.dto.UploadFileDto;
import com.mujin.keji.collectionsystem.exception.ApiException;
import com.mujin.keji.collectionsystem.exception.ExceptionEngine;
import com.mujin.keji.collectionsystem.exception.ServerException;
import com.mujin.keji.collectionsystem.http.Api;
import com.mujin.keji.collectionsystem.http.HttpUtils;
import com.mujin.keji.collectionsystem.listeners.CustomItemClickListener;
import com.mujin.keji.collectionsystem.module.login.dto.LoginDto;
import com.mujin.keji.collectionsystem.module.login.dto.UserDto;
import com.mujin.keji.collectionsystem.module.login.vo.LoginCollectionVo;
import com.mujin.keji.collectionsystem.module.main.vo.ErrorVo;
import com.mujin.keji.collectionsystem.module.outboundtask.dto.BoundTaskDto;
import com.mujin.keji.collectionsystem.module.outboundtask.viewmodel.BoundTaskListViewModel;
import com.mujin.keji.collectionsystem.module.outboundtask.viewmodel.PhotoViewModel;
import com.mujin.keji.collectionsystem.module.outboundtask.viewmodel.RecordViewModel;
import com.mujin.keji.collectionsystem.module.outboundtask.views.BoundDetailActivity;
import com.mujin.keji.collectionsystem.module.outboundtask.views.CaseInformationActivity;
import com.mujin.keji.collectionsystem.module.outboundtask.vo.ApplyCaseVo;
import com.mujin.keji.collectionsystem.module.outboundtask.vo.SaveVisitRecordReq;
import com.mujin.keji.collectionsystem.module.outboundtask.vo.UploadWithBase64Request;
import com.mujin.keji.collectionsystem.module.outboundtask.vo.VisitFileVo;
import com.mujin.keji.collectionsystem.module.updata.adapter.UpDataListAdapter;
import com.mujin.keji.collectionsystem.module.updata.dto.ShowVisitUserDto;
import com.mujin.keji.collectionsystem.module.updata.dto.VisitUserDto;
import com.mujin.keji.collectionsystem.module.updata.vo.UpLoadFileVo;
import com.mujin.keji.collectionsystem.module.updata.vo.UploadVo;
import com.mujin.keji.collectionsystem.net.NetworkUtil;
import com.mujin.keji.collectionsystem.utils.AssambleReqUtil;
import com.mujin.keji.collectionsystem.utils.DateUtil;
import com.mujin.keji.collectionsystem.utils.DisplayUtil;
import com.mujin.keji.collectionsystem.utils.Dom4jUtil;
import com.mujin.keji.collectionsystem.utils.EmptyUtils;
import com.mujin.keji.collectionsystem.utils.FileUtil;
import com.mujin.keji.collectionsystem.utils.IpUtils;
import com.mujin.keji.collectionsystem.utils.SPUtil;
import com.mujin.keji.collectionsystem.utils.ToastUtils;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnRefreshListener;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.greenrobot.eventbus.EventBus;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Response;

/**
 * 提交数据Activity界面
 * 所有案件的文件
 *
 * @author weishixiong
 * @Time 2018-03-22
 */

public class UpLoadAllUserDataActivity extends BaseActivity implements View.OnClickListener, CustomItemClickListener {

    private static final String LOGGER = "上传数据";

    private ProgressBar progressBar;
    private TextView tvSpeed;
    private TextView tvVisitCount;
    private TextView tvFileCount;
    private RecyclerView recyclerView;
    private TextView tvProgress;
    private LinearLayout btnOk;
    private LinearLayoutManager linearLayoutManager;
    private List<VisitUserDto> visitUserDtos;
    private RecordViewModel recordViewModel;
    private PhotoViewModel photoViewModel;
    private UpDataListAdapter upDataListAdapter;
    private boolean isUploading;
    private List<File> fileList;
    private List<File> photoAndRecordFiles;
    private List<ShowVisitUserDto> showVisitUserDtoList;
    private List<String> applyIdList;
    private List<UpLoadFileVo> upLoadFileVoList;//封装多次上传参数

    //总的大小
    private int allSize;

    private int successSize;//上传成功的数量


    private BoundTaskListViewModel boundTaskListViewModel;
    private List<BoundTaskDto> mBoundTaskDtoList;
    private LinearLayout llNoData;
    private TextView tvNoData;
    private RelativeLayout rlHaveData;
    private SmartRefreshLayout srNoData;
    private SmartRefreshLayout srHasData;
    private ConnectivityManager manager;

    /**
     * 获取拜访任务列表数据
     *
     * @param
     */
    public void initBoundTaskDtoData() {
        allSize = 0;
        successSize = 0;
        ApplyCaseVo applyCaseVo = new ApplyCaseVo();
        applyCaseVo.setTimeSort(2);
        applyCaseVo.setStatus(2);
        boundTaskListViewModel = ViewModelProviders.of(this).get(BoundTaskListViewModel.class);


        String userName = SPUtil.getData(Constant.SP.SP, Constant.SP.USER, String.class, null);
        //SQLite直接获取数据
        Flowable<List<VisitApplyBean>> flowable = AppDataBase.getInstance(this).getVisitDao().queryVisitListByStatus(VisitStatusEnum.VISIT_YIWAIFANG.getCode(), userName);

        flowable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<List<VisitApplyBean>>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(100);
                    }

                    @Override
                    public void onNext(List<VisitApplyBean> visitApplyBeans) {
                        getLoadingDialog().dismiss();
                        srNoData.finishRefresh();
                        srHasData.finishRefresh();
                        getLoadingDialog().dismiss();
                        if (EmptyUtils.isNotEmpty(visitApplyBeans)) {
                            List<BoundTaskDto> lists = new ArrayList<>();


                            for (VisitApplyBean visitApplyBean : visitApplyBeans) {
                                PropertyFilter profilter = new PropertyFilter() {
                                    public boolean apply(Object object, String name, Object value) {
                                        if (name.equalsIgnoreCase("status")) {
                                            //false表示last字段将被排除在外
                                            return false;
                                        }
                                        return true;
                                    }
                                };

                                String json = JSONObject.toJSONString(visitApplyBean, profilter);
                                BoundTaskDto boundTaskDto = JSONObject.parseObject(json, BoundTaskDto.class);
                                boundTaskDto.setStatus(VisitStatusEnum.getStatusByCode(visitApplyBean.getStatus()));
                                boundTaskDto.setId(visitApplyBean.getVisitApplyId());
                                lists.add(boundTaskDto);
                            }

                            mBoundTaskDtoList = lists;
                            initListView();
                            photoAndRecordFiles = new ArrayList<>();
                            fileList = new ArrayList<>();
                            visitUserDtos = new ArrayList<>();
                            //获取待上传的录音文件
                            getRecordData();
                            //获取待上传的图片文件
                            getPhotoData();
                            //过滤只有已外访的数据
                            filierDatas();
                        } else {
                            srHasData.setVisibility(View.GONE);
                            llNoData.setVisibility(View.VISIBLE);
                            tvNoData.setText("没有待上传文件");
                            return;
                        }

                    }

                    @Override
                    public void onError(Throwable t) {
                        getLoadingDialog().dismiss();
                        ApiException exception = ExceptionEngine.handleException(t);
                        ToastUtils.showToast(exception.getCode() + "-" + exception.getMsg());


                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }

    //已外访的ID
    private List<String> hasBoundIds;


    //过滤只有已外访的数据
    private void filierDatas() {

        try {
            hasBoundIds = new ArrayList<>();
            //构造已经外访的ID 数组
            for (int i = 0; i < mBoundTaskDtoList.size(); i++) {
                hasBoundIds.add(String.valueOf(mBoundTaskDtoList.get(i).getId()));
            }
            recursiveTraversal();
            //刷新UI
            ruslushListView();
            //初始化进度条
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**
     * 递归遍历
     */
    private void recursiveTraversal() {
        for (int i = 0; i < applyIdList.size(); i++) {
            if (!hasBoundIds.contains(applyIdList.get(i))) {
                applyIdList.remove(i);
                showVisitUserDtoList.remove(i);
                //重新遍历
                recursiveTraversal();
            }


        }
    }

    @Override
    protected void createViewModel() {

        photoViewModel = ViewModelProviders.of(this).get(PhotoViewModel.class);
        recordViewModel = ViewModelProviders.of(this).get(RecordViewModel.class);
        boundTaskListViewModel = ViewModelProviders.of(this).get(BoundTaskListViewModel.class);
    }

    @Override
    protected void onCreate(@android.support.annotation.Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        CcsApplication.addActivity(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        CcsApplication.removeActivity(this);

    }

    @Override
    public int intiLayout() {
        return R.layout.activity_uploaddata;
    }

    @Override
    public void initView() {
        setCenterTitle("数据上传", "#FFFFFF");
        setleftImage(R.drawable.image_arrow_left_white, true, null);


        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        tvSpeed = (TextView) findViewById(R.id.tv_speed);
        tvVisitCount = (TextView) findViewById(R.id.tv_visit_count);
        tvFileCount = (TextView) findViewById(R.id.tv_file_count);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        tvProgress = (TextView) findViewById(R.id.tv_progress);
        btnOk = (LinearLayout) findViewById(R.id.btn_ok);
        rlHaveData = (RelativeLayout) findViewById(R.id.rl_have_data);
        llNoData = (LinearLayout) findViewById(R.id.ll_no_data);
        tvNoData = (TextView) findViewById(R.id.tv_no_data);
        srNoData = (SmartRefreshLayout) findViewById(R.id.sr_no_data);
        srHasData = (SmartRefreshLayout) findViewById(R.id.sr_has_data);
        srHasData.setEnableLoadMore(false);
        srNoData.setEnableLoadMore(false);
        srHasData.setEnableRefresh(false);
        srHasData.setHeaderHeight(DisplayUtil.dip2px(this, 16));
        srNoData.setHeaderHeight(DisplayUtil.dip2px(this, 16));
    }

    /**
     * 初始化ui
     */
    private void initListView() {
        showVisitUserDtoList = new ArrayList<>();
        applyIdList = new ArrayList<>();
        linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
        upDataListAdapter = new UpDataListAdapter(this, showVisitUserDtoList, this);
        recyclerView.setAdapter(upDataListAdapter);
    }

    @Override
    public void initData() {

        appDataBase = AppDataBase.getInstance(UpLoadAllUserDataActivity.this);
        getLoadingDialog().showDialog();
        allSize = 0;
        successSize = 0;
        initBoundTaskDtoData();
        getLoadingDialog().showDialog();
        allSize = 0;
        successSize = 0;
        initBoundTaskDtoData();
    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    /**
     * 刷新UI
     */
    private void ruslushListView() {
        int fileCount = 0;

        if (EmptyUtils.isNotEmpty(showVisitUserDtoList)) {
            tvVisitCount.setText(showVisitUserDtoList.size() + "");

            //删掉0B的文件
            deleteZeroFile();

            //计算数量
            for (int i = 0; i < showVisitUserDtoList.size(); i++) {
                fileCount += showVisitUserDtoList.get(i).getVisitUserDtoList().size();
            }

            upDataListAdapter.notifyDataSetChanged();
            tvFileCount.setText(fileCount + "");


            initProgress(fileCount);
        } else {
            tvVisitCount.setText("0");
            tvFileCount.setText("0");
        }
        if (upDataListAdapter.getItemCount() == 0) {
            srHasData.setVisibility(View.GONE);
            llNoData.setVisibility(View.VISIBLE);
            tvNoData.setText("没有待上传文件");
        } else {
            srHasData.setVisibility(View.VISIBLE);
            llNoData.setVisibility(View.GONE);
        }

    }

    /**
     * 递归遍历
     */
    private void deleteZeroFile() {

        for (int i = 0; i < showVisitUserDtoList.size(); i++) {

            for (int j = 0; j < showVisitUserDtoList.get(i).getVisitUserDtoList().size(); j++) {
                File file = showVisitUserDtoList.get(i).getVisitUserDtoList().get(j).getFile();
                if (file == null || IpUtils.fileToBase64String(file) == null) {
                    showVisitUserDtoList.get(i).getVisitUserDtoList().remove(j);

                    if (showVisitUserDtoList.get(i).getVisitUserDtoList().size() == 0) {
                        showVisitUserDtoList.remove(i);
                    }
                    deleteZeroFile();

                }
            }
        }

    }


    /**
     * 构造要展示的数据
     */
    private void initShowVisitUserDtoData() {
        applyIdList.clear();
        showVisitUserDtoList.clear();
        for (int i = 0; i < visitUserDtos.size(); i++) {
            String fileName = visitUserDtos.get(i).getFileName();
            for (int k = 0; k < photoAndRecordFiles.size(); k++) {
                if (photoAndRecordFiles.get(k).getName().contains(fileName)) {
                    visitUserDtos.get(i).setFile(photoAndRecordFiles.get(k));
                }
            }
            //判断是否包含key
            if (applyIdList.contains(visitUserDtos.get(i).getVisitApplyId())) {
                int index = applyIdList.indexOf(visitUserDtos.get(i).getVisitApplyId());
                showVisitUserDtoList.get(index).getVisitUserDtoList().add(visitUserDtos.get(i));
            } else {
                ShowVisitUserDto showVisitUserDto = new ShowVisitUserDto();
                showVisitUserDto.setVisitApplyId(visitUserDtos.get(i).getVisitApplyId());
                showVisitUserDto.setUserAccount(visitUserDtos.get(i).getUserAccount());
                List<VisitUserDto> v = new ArrayList<>();
                v.add(visitUserDtos.get(i));
                showVisitUserDto.setVisitUserDtoList(v);
                showVisitUserDtoList.add(showVisitUserDto);
                applyIdList.add(visitUserDtos.get(i).getVisitApplyId());
            }
        }
        filterUserFile();

    }

    /**
     * 过滤掉非当前用户的文件
     */
    private void filterUserFile() {
        if (!EmptyUtils.isNotEmpty(showVisitUserDtoList)) {
            return;
        }
        LoginDto dto = SPUtil.getData(Constant.SP.SP, Constant.SP.LOGIN_KEY, LoginDto.class, null);
        String userCount = dto.getUserAccount();
        if (TextUtils.isEmpty(userCount)) {
            return;
        }
        for (int i = 0; i < showVisitUserDtoList.size(); i++) {
            if (!(userCount.equals(showVisitUserDtoList.get(i).getUserAccount()))) {
                showVisitUserDtoList.remove(i);
                applyIdList.remove(i);
                filterUserFile();
            }
        }
    }

    /**
     * 获取待上传的录音文件
     */
    private void getRecordData() {
        recordViewModel.getFileCountLiveData().observe(this, new Observer<List<File>>() {
            @Override
            public void onChanged(@android.support.annotation.Nullable List<File> files) {
                initFiles(files);
            }
        });

    }

    /**
     * 获取待上传的图片文件
     */
    private void getPhotoData() {
        photoViewModel.getFileCountLiveData().observe(this, new Observer<List<File>>() {
            @Override
            public void onChanged(@android.support.annotation.Nullable List<File> files) {
                initFiles(files);
            }
        });
    }

    /**
     * 获取文件成功回调
     * 刷新列表
     *
     * @param files
     */
    private void initFiles(List<File> files) {

        if (EmptyUtils.isNotEmpty(files)) {
            fileList.addAll(files);
            for (int i = 0; i < files.size(); i++) {
                if (files.get(i).getName().endsWith(".txt")) {
                    try {
                        String visitStr = FileUtil.readJsonFromFile(files.get(i));
                        visitUserDtos.add(JSONObject.parseObject(visitStr, VisitUserDto.class));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    photoAndRecordFiles.add(files.get(i));
                }

            }

            //初始化需要展示的数据
            initShowVisitUserDtoData();


        }


    }

    /**
     * 初始化进度条
     */
    private void initProgress(int size) {

        allSize = size;
        progressBar.setMax(allSize);
        //
        tvProgress.setText("0/" + allSize);

    }

    @Override
    public void initListener() {
        btnOk.setOnClickListener(this);
        srNoData.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                initBoundTaskDtoData();
            }
        });
        srHasData.setOnRefreshListener(new OnRefreshListener() {
            @Override
            public void onRefresh(@NonNull RefreshLayout refreshLayout) {
                initBoundTaskDtoData();
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_ok:
                if (!NetworkUtil.isNetworkAvailable(this)) {
                    ToastUtils.showToast("请开启手机网络");
                    return;
                }
                initUploadData();
                break;
        }
    }

    /**
     * 初始化多次上传的数据
     * upLoadFileVoList
     */
    private void initUploadData() {
        if (!EmptyUtils.isNotEmpty(showVisitUserDtoList)) {
            return;
        }
        btnOk.setEnabled(false);
        btnOk.setBackgroundResource(R.drawable.shape_button_select_dark_bg);
        isUploading = true;
        upLoadFileVoList = new ArrayList<>();
        for (int i = 0; i < showVisitUserDtoList.size(); i++) {
            UploadVo vo = new UploadVo();
            vo.setVisitApplyId(showVisitUserDtoList.get(i).getVisitApplyId());
            vo.setRecordTime(showVisitUserDtoList.get(i).getVisitUserDtoList().get(0).getFileTime());
            vo.setVisitorAddress(showVisitUserDtoList.get(i).getVisitUserDtoList().get(0).getFileAdress());
            List<File> uploadFiles = new ArrayList<>();
            for (int j = 0; j < showVisitUserDtoList.get(i).getVisitUserDtoList().size(); j++) {
                uploadFiles.add(showVisitUserDtoList.get(i).getVisitUserDtoList().get(j).getFile());
            }
            UpLoadFileVo upLoadFileVo = new UpLoadFileVo();
            upLoadFileVo.setVo(vo);
            upLoadFileVo.setUploadFiles(uploadFiles);
            upLoadFileVoList.add(upLoadFileVo);
        }
        upLoad();
    }

    private AppDataBase appDataBase;

    /**
     * 实现上传
     */
    private void upLoad() {
        //上传文件
        getLoadingDialog().showDialog();


        //查询用户信息
        String userName = SPUtil.getData(Constant.SP.SP, Constant.SP.USER, String.class, null);
        Flowable<List<UserDto>> flowable = appDataBase.getUserDao().findUserList(userName);
        flowable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<List<UserDto>>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(100);
                        Log.e(TAG, "Subscription: " + s);
                    }

                    @Override
                    public void onNext(List<UserDto> userDtos) {
                        if (!EmptyUtils.isNotEmpty(userDtos)) {
                            ToastUtils.showToast("获取用户信息失败");
                            getLoadingDialog().dismiss();
                            btnOk.setEnabled(true);
                            btnOk.setBackgroundResource(R.drawable.shape_button_select_bg);
                            return;
                        }
                        Log.e(TAG, "onNext: " + userDtos.toString());
                        UserDto userDto = userDtos.get(0);
                        //获取用户session
                        initLoginSession(userDto);


                    }

                    @Override
                    public void onError(Throwable t) {

                        initErrorInfo("upLoad()", "614", "t.getMessage()");

                        getLoadingDialog().dismiss();
                        Log.e(TAG, "onError: " + t);
                        getLoadingDialog().dismiss();
                        ApiException exception = ExceptionEngine.handleException(t);
                        ToastUtils.showToast(exception.getCode() + "-" + exception.getMsg());

                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });


    }


    /**
     * 获取 session
     *
     * @param userDto
     * @return
     */
    private void initLoginSession(UserDto userDto) {
        new Thread() {
            @Override
            public void run() {
                super.run();
                LoginCollectionVo loginCollectionVo = new LoginCollectionVo();
                loginCollectionVo.setAccount(userDto.getUsername());
                loginCollectionVo.setPassword(userDto.getPassword());
                loginCollectionVo.setMerchantId(Constant.Server.merchantId);
                loginCollectionVo.setPlatform(Constant.Server.platform);

                String loginCollectionJson = JSON.toJSON(loginCollectionVo).toString();
                try {
                    Log.i(TAG, "请求参数loginCollectionJson:" + loginCollectionJson);
                    //
                    Response response = HttpUtils.post(Constant.Server.ROOT_URL + "login/", loginCollectionJson);
                    Log.i(TAG, "登陆接口返回response:" + response);
                    String rtn = response.body().string();
                    Log.i(TAG, "登陆接口返回内容:" + rtn);
                    Document doc = DocumentHelper.parseText(rtn);
                    JSONObject json = new JSONObject();
                    Dom4jUtil.dom4j2Json(doc.getRootElement(), json);
                    JSONObject jsonObjectTemp = (JSONObject) json.get("data");
                    if (EmptyUtils.isNotEmpty(jsonObjectTemp)) {

                        String session = jsonObjectTemp.get("session") + "";
                        Message msg = Message.obtain();
                        msg.what = 2001;
                        msg.obj = session;
                        handler.sendMessage(msg);

                    } else {
                        String code = (String) json.get("code");
                        String msg = (String) json.get("msg");
                        Message message = Message.obtain();
                        message.obj = msg + "-" + code;
                        handler.sendMessage(message);
                        initErrorInfo("initLoginSession()", "690", msg + "-" + code);

                    }


                } catch (Exception e) {
                    Message message = Message.obtain();
                    message.obj = "客户端异常，请稍候再试" + e.getMessage();
                    handler.sendMessage(message);

                    initErrorInfo("initLoginSession()", "695", e.getMessage());

                }

            }
        }.start();


    }

    private String session;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 200) {
                //刷新列视图
                showVisitUserDtoList.clear();
                ruslushListView();
                CcsApplication.clearSpecifyActivities(new Class[]{CaseInformationActivity.class});
                CcsApplication.clearSpecifyActivities(new Class[]{BoundDetailActivity.class});

                getLoadingDialog().dismiss();
                ToastUtils.showToast("已更新完成");
            }
            /**
             * 拿到session 完之后 去上传
             */
            else if (msg.what == 2001) {
                session = (String) msg.obj;
                initToUpload(session);
            } else if (msg.what == 300) {
                //刷新列视图
                getLoadingDialog().dismiss();
                //刷新列视图
                ToastUtils.showToast("客户端异常");

                initErrorInfo("handleMessage()", "755", "msg.what == 300");

            } else {
                getLoadingDialog().dismiss();
                ToastUtils.showToast((String) msg.obj);
                btnOk.setEnabled(true);
                btnOk.setBackgroundResource(R.drawable.shape_button_select_bg);
            }
        }
    };
    private List<ParamVo> list;

    /**
     * 初始化上传
     *
     * @param session
     */
    private void initToUpload(String session) {
        if (successSize >= allSize) {
            return;
        }
        //第一次上传的时候 先组装参数
        if (list == null) {
            applyIds = new ArrayList<>();
            //上传文件
            list = new ArrayList<>();
            for (int j = 0; j < upLoadFileVoList.size(); j++) {
                UpLoadFileVo upLoadFileVo = upLoadFileVoList.get(j);
                //ID 组装
                applyIds.add(Long.parseLong(upLoadFileVoList.get(j).getVo().getVisitApplyId()));
                //
                UploadVo uploadVo = upLoadFileVo.getVo();
                List<File> files = new ArrayList<>();
                files.addAll(upLoadFileVo.getUploadFiles());

                for (int i = 0; i < files.size(); i++) {
                    VisitFileVo visitFileVo = new VisitFileVo();
                    File file = files.get(i);
                    //上传
                    List<VisitFileVo> visitFileVos = new ArrayList<>();
                    List<UploadWithBase64Request> requests = new ArrayList<>();
                    UploadWithBase64Request uploadWithBase64Request = new UploadWithBase64Request();
                    visitFileVo.setVisitApplyId(Long.valueOf(uploadVo.getVisitApplyId()));
                    uploadWithBase64Request.setFileName(file.getName());
                    try {

                        String content = IpUtils.fileToBase64String(file);
                        if (content == null) {
                            Log.e(TAG, "initToUpload: content为空，执行下一个");
                            continue;
                        }
                        uploadWithBase64Request.setContent(content);

                        uploadWithBase64Request.setFileNameExt(file.getName().split("\\.")[1]);
                        requests.add(uploadWithBase64Request);
                        visitFileVo.setVisitApplyId(Long.valueOf(uploadVo.getVisitApplyId()));
                        visitFileVo.setUploadWithBase64RequestList(requests);
                        visitFileVos.add(visitFileVo);

                    } catch (Exception e) {
                        e.printStackTrace();

                        initErrorInfo("initToUpload()", "801", e.getMessage());

                    }

                    //加到一个数组
                    list.add(new ParamVo(visitFileVos, session, uploadVo.getVisitApplyId(), file));


                }


            }
        }

        //先保存外访记录
        new Thread() {
            @Override
            public void run() {
                //重新获取 最新的ID 集合
                Set<String> setApplyIds = new HashSet<>(applyIdList);
                //构建上传的记录集合
                recordReqs = new ArrayList<>();
                // for (String applyIdStr : setApplyIds) {
                //更新后台外访记录
                uploadVisitRecord(setApplyIds);
                //   }

            }
        }.start();

        //开始上传
        startToUpload();

    }


    private void startToUpload() {
        Log.e(TAG, "上传第 " + successSize + "个文件");
        //上传
        uploadFile(list.get(successSize).getVisitFileVos(), session, list.get(successSize).getFile());
    }

    private String errorInfoUrl = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "aaerrors" + "/";


    /**
     * 上传文件
     *
     * @param visitFileVoList
     * @param session
     * @return
     */
    private void uploadFile(List<VisitFileVo> visitFileVoList, String session, File file) {

        BaseVo baseVo = AssambleReqUtil.assambleReqMap(SyncDataMethod.visitUpload, session, visitFileVoList);
        Log.e(TAG, "uploadFile: " + baseVo.toString());
        Log.e(TAG, "uploadFile: 正在上传文件...." + file.getName());


        Flowable<UploadFileDto> flowable = Api.uploadSingle(baseVo);
        flowable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<UploadFileDto>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(100);
                        Log.e(TAG, "onSubscribe: " + s);

                    }

                    @Override
                    public void onNext(UploadFileDto dto) {

                        if (EmptyUtils.isNotEmpty(dto) && EmptyUtils.isNotEmpty(dto.getVisit_app_file_upload_response())) {
                            Boolean result = dto.getVisit_app_file_upload_response().isData();
                            if (result) {
                                successSize++;
                                Log.e(TAG, "----successSize: " + successSize);
                                Log.e(TAG, "----allSize: " + allSize);
                                progressBar.setProgress(successSize);
                                tvProgress.setText(successSize + "/" + allSize);

                                new Thread() {
                                    @Override
                                    public void run() {
                                        super.run();
                                        String path = file.getPath();
                                        for (int i = 0; i < upLoadFileVoList.size(); i++) {
                                            for (int j = 0; j < upLoadFileVoList.get(i).getUploadFiles().size(); j++) {
                                                if (upLoadFileVoList.get(i).getUploadFiles().get(j).getPath().equals(path)) {
                                                    Log.e(TAG, "清掉之前: " + upLoadFileVoList.get(i).getUploadFiles().size());
                                                    upLoadFileVoList.get(i).getUploadFiles().remove(file);
                                                    Log.e(TAG, "run: 清掉的" + file);
                                                    Log.e(TAG, "清掉之后: " + upLoadFileVoList.get(i).getUploadFiles().size());
                                                    break;
                                                }

                                            }
                                        }

                                        File textFile = new File(file.getPath().substring(0, file.getPath().length() - 4) + ".txt");
                                        FileUtil.deleteFile(textFile);
                                        FileUtil.deleteFile(file);
                                        Log.e(TAG, "run: " + file);
                                        Log.e(TAG, "run: " + textFile);
                                        System.gc();


                                    }
                                }.start();

                                if (successSize == allSize) {
                                    ToastUtils.showLongToast("上传完成，正在更新案件状态");
                                    new Thread() {
                                        @Override
                                        public void run() {
                                            getLoadingDialog().dismiss();
                                            finishApplay();
                                        }
                                    }.start();

                                } else {
                                    startToUpload();
                                }

                            } else {
                                btnOk.setEnabled(true);
                                btnOk.setBackgroundResource(R.drawable.shape_button_select_bg);
                                getLoadingDialog().dismiss();
                                ToastUtils.showToast("上传失败" + result);
                                initErrorInfo("uploadFile()", "973", "result:" + result);


                            }
                        } else {

                            getLoadingDialog().dismiss();
                            btnOk.setEnabled(true);
                            btnOk.setBackgroundResource(R.drawable.shape_button_select_bg);
                            Log.e(TAG, "onNext: -----------");
                            if (EmptyUtils.isNotEmpty(dto.getError_response())) {
                                Log.e(TAG, "onNext:++++");
                                ToastUtils.showToast(dto.getError_response().getMsg() + "-" + dto.getError_response().getSub_code());
                                initErrorInfo("uploadFile()", "1008", dto.getError_response().getMsg() + "-" + dto.getError_response().getSub_code());

                            } else {
                                Log.e(TAG, "onNext:???");
                                ToastUtils.showToast("上传失败");
                            }
                        }

                    }

                    @Override
                    public void onError(Throwable t) {
                        getLoadingDialog().dismiss();
                        ApiException exception = ExceptionEngine.handleException(t);
                        ToastUtils.showToast(exception.getCode() + "-" + exception.getMsg());
                        getLoadingDialog().dismiss();
                        btnOk.setEnabled(true);
                        btnOk.setBackgroundResource(R.drawable.shape_button_select_bg);
                        initErrorInfo("uploadFile()", "1025", t.getMessage());


                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });

    }

    private List<SaveVisitRecordReq> recordReqs;

    /**
     * 上传记录
     *
     * @param setApplyIds 上传的ID 集合
     */
    public void uploadVisitRecord(Set<String> setApplyIds) {

        List<Long> idList = new ArrayList<>();
        Iterator<String> it = setApplyIds.iterator();
        while (it.hasNext()) {
            String id = it.next();
            idList.add(Long.parseLong(id));
        }

        //通过ID 集合去查询 列表
        //上传外访记录
        Flowable<List<SaveVisitRecordBean>> flowableQuery = appDataBase.getVisitDao().queryAllVisitRecordList(idList);
        flowableQuery.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<List<SaveVisitRecordBean>>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(1);
                        Log.e(TAG, "Subscription: " + s);
                    }

                    //返回列表数据
                    @Override
                    public void onNext(List<SaveVisitRecordBean> saveVisitRecordBeanList) {

                        for (int i = 0; i < saveVisitRecordBeanList.size(); i++)
                        {
                            SaveVisitRecordBean saveVisitRecordBean = saveVisitRecordBeanList.get(i);
                            String json = JSONObject.toJSONString(saveVisitRecordBean);
                            SaveVisitRecordReq saveVisitRecordReq = JSONObject.parseObject(json, SaveVisitRecordReq.class);
                            if (null != saveVisitRecordBean.getIsKown()) {
                                saveVisitRecordReq.setIsKown(saveVisitRecordBean.getIsKown() == 0 ? "no" : "yes");
                            }
                            saveVisitRecordReq.setEmailSituation(saveVisitRecordBean.getEmailSituation());
                            //外访开始时间
                            saveVisitRecordReq.setBeginTime(saveVisitRecordBean.getVisitTimeStr());
                            //外访结速地址
                            saveVisitRecordReq.setVisitAddress(saveVisitRecordBean.getVisitEndAddress());
                            saveVisitRecordReq.setHouseAppliance(HouseApplianceEnum.find(saveVisitRecordBean.getHouseAppliance()));
                            saveVisitRecordReq.setInnerDecoration(InnerDecorationEnum.find(saveVisitRecordBean.getInnerDecoration()));
                            saveVisitRecordReq.setLivingSituation(LivingSituationEnum.find(saveVisitRecordBean.getLivingSituation()));
                            saveVisitRecordReq.setRepayPower(RepayPowerEnum.find(saveVisitRecordBean.getRepayPower()));
                            saveVisitRecordReq.setVisitHouse(VisitHouseEnum.find(saveVisitRecordBean.getVisitHouse()));
                            saveVisitRecordReq.setVisitMark(saveVisitRecordBean.getCaseDevelopment());
                            saveVisitRecordReq.setVisitCode(saveVisitRecordBean.getTaskCode());
                            //构建上传的集合
                            recordReqs.add(saveVisitRecordReq);

                        }

                        //集合 保存到服务器
                        saveRecordToServer(recordReqs);


//                        initErrorInfo("uploadVisitRecord()", "1116", "setApplyIds的长度：" + setApplyIds.size() + "--recordReqs的长度：" + recordReqs.size());
//                        //组装的数据 等于 ID 的长度 就是案件的数  就去上传到服务器
//                        if (recordReqs.size() == setApplyIds.size()) {
//                            //保存到服务器
//                            initErrorInfo("uploadVisitRecord()", "1116", "开始把记录提交到服务器");
                        // saveRecordToServer(recordReqs);
                        //}
                    }

                    @Override
                    public void onError(Throwable t) {
                        getLoadingDialog().dismiss();
                        Log.e(TAG, "onError: " + t);
                        getLoadingDialog().dismiss();
                        ApiException exception = ExceptionEngine.handleException(t);

                        ToastUtils.showLongToast(exception.getCode() + "-" + exception.getMsg());
                        initErrorInfo("uploadVisitRecord()", "1116", t.getMessage());
                    }

                    @Override
                    public void onComplete() {
                        Log.e(TAG, "onComplete: ");
                    }
                });


    }

    /**
     * 把整 组外访记录上传
     *
     * @param recordReqs
     */
    private void saveRecordToServer(List<SaveVisitRecordReq> recordReqs) {
        BaseVo baseVo = AssambleReqUtil.assambleReqMap(SyncDataMethod.saveRecords, session, recordReqs);
        //更新用户信息
        Flowable<JSONObject> flowable = Api.updateApplyStatus(baseVo);
        flowable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<JSONObject>() {
                    @Override
                    public void onSubscribe(Subscription s) {
                        s.request(1);
                    }

                    @Override
                    public void onNext(JSONObject result) {
                        initErrorInfo("uploadVisitRecord()", "1116", "记录提交到服务器成功了");
                        Log.e(TAG, "onNext: " + result);

                    }

                    @Override
                    public void onError(Throwable t) {
                        getLoadingDialog().dismiss();
                        ApiException exception = ExceptionEngine.handleException(t);
                        ToastUtils.showToast(exception.getCode() + "-" + exception.getMsg());
                        initErrorInfo("uploadVisitRecord()", "1116", "记录提交到服务器失败了");
                        initErrorInfo("uploadVisitRecord()", "1157", t.getMessage());

                    }

                    @Override
                    public void onComplete() {

                    }
                });

    }

    private List<Long> applyIds;

    /**
     * 完成外访
     *
     * @param
     */
    private void finishApplay() {
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    for (int i = 0; i < applyIds.size(); i++) {
                        VisitDao visitDao = appDataBase.getVisitDao();
                        VisitApplyBean visitApplyBean = visitDao.queryVisitList(applyIds.get(i));
                        visitApplyBean.setStatus(VisitStatusEnum.VISIT_WANCHENG.getCode());
                        visitDao.updateVisitApply(visitApplyBean);
                        //更新条数
                        VisitCountBean visitCountBean = visitDao.findVisitCountDetail();
                        visitCountBean.setVisited((visitCountBean.getVisited() == null ? 0 : visitCountBean.getVisited()) - 1);
                        visitCountBean.setFinish((visitCountBean.getFinish() == null ? 0 : visitCountBean.getFinish()) + 1);
                        visitDao.updateVisitCount(visitCountBean);
                    }
                } catch (Exception e) {
                    handler.sendEmptyMessage(300);
                    initErrorInfo("finishApplay(", "1196", e.getMessage() + "保存外访记录报错了");

                }
                handler.sendEmptyMessage(200);


            }
        }.start();


    }

    private void initErrorInfo(String method, String line, String msg) {
        new Thread() {

            @Override
            public void run() {
                ErrorVo vo = new ErrorVo();
                vo.setMethodName(method);
                vo.setLine(line);
                vo.setMessage(msg);
                String errorStr = JSONObject.toJSONString(vo);
                FileUtil.writeJsonToFile(errorInfoUrl + DateUtil.formatDate("yyyy-MM-dd--HH:mm:ss", new Date()) + ".txt", errorStr);
            }
        }.start();


    }

    @Override
    public void onItemClick(View view, int position) {
        startActivity(new Intent(this, UploadSingleUserActivity.class));
        EventBus.getDefault().postSticky(showVisitUserDtoList.get(position));
    }
}
